package com.agent.action.service.Impl;

import com.agent.action.client.DifyAgentClient;
import com.agent.action.entity.AgentChatEntity;
import com.agent.action.entity.AgentMessageHistoryEntity;
import com.agent.action.entity.DifyAgentEntity;
import com.agent.action.param.ChatParam;
import com.agent.action.param.ConversationNameParam;
import com.agent.action.param.PauseParam;
import com.agent.action.service.AgentService;
import com.agent.action.vo.ChatHistoryVO;
import com.agent.action.vo.ChatVO;
import com.agent.commons.enums.Agent;
import com.agent.commons.other.MessageHistory;
import com.agent.commons.utils.RabbitMqUtil;
import com.agent.feign.client.RagClient;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Flux;
import reactor.core.publisher.SignalType;
import static com.agent.commons.constants.RabbitMqConstants.*;

import java.util.ArrayList;
import java.util.List;

@Slf4j
@Service
public class AgentServiceImpl implements AgentService {

    @Resource
    private DifyAgentClient<AgentChatEntity> difyAgentClient;

    @Resource
    private RagClient ragClient;
    @Override
    public Flux<ChatVO> chat(ChatParam chatParam,MessageHistory messageHistory) {
        DifyAgentEntity<AgentChatEntity> difyAgentEntity = new DifyAgentEntity<>();
        AgentChatEntity agentChatEntity = new AgentChatEntity();
        //TODO 获取RAG检索出的知识
        agentChatEntity.setKnowledge(ragClient.get(chatParam.getQuery()).toString());
        if(chatParam.getConversationId()==null) {
            agentChatEntity.setName(chatParam.getQuery());
            messageHistory.setConversationName(chatParam.getQuery());
        }
        //TODO 添加会话名称
        difyAgentEntity.setInputs(agentChatEntity);
        difyAgentEntity.setQuery(chatParam.getQuery());
        difyAgentEntity.setConversation_id(chatParam.getConversationId());
        difyAgentEntity.setUser(chatParam.getUserId());
        difyAgentClient.url("chat-messages");
        return ActionFlux(difyAgentEntity,messageHistory);
    }

    @Override
    public List<ChatHistoryVO> getMessageHistory(AgentMessageHistoryEntity message) {
        difyAgentClient.url("messages");
        JSONObject messageHistory = difyAgentClient.getMessageHistory(message);
        return getListChatHistory(messageHistory.get("data").toString());
    }

    /**
     * 暂停智能体响应
     * @param pauseParam
     * @return
     */
    @Override
    public void pause(PauseParam pauseParam) {
        difyAgentClient.pause(pauseParam);
    }


    /**
     * 响应流处理Flux<String>->Flux<ChatVO>
     * @return
     */
    private Flux<ChatVO> ActionFlux(DifyAgentEntity<AgentChatEntity> difyAgentEntity,MessageHistory message) {
        StringBuilder content = new StringBuilder();
        log.info("准备开始流式传输!{}",message);
        List<String> conversationId=new ArrayList<>();
        return difyAgentClient.chat(difyAgentEntity).map(JSONObject::parseObject)
                .filter(jsonObject->jsonObject.get("event").equals("agent_message"))//过滤数据块
                .map(jsonObject -> {
                    ChatVO chatVO=new ChatVO();
                    String task_id=jsonObject.get("task_id").toString();//获取任务id(task_id)
                    String text=jsonObject.get("answer").toString();//分块获取回答
                    String conversation_id=jsonObject.get("conversation_id").toString();//获取任务id
                    log.error("回答:{},会话id:{}",text,conversation_id);
                    //构建输出数据
                    content.append(text);
                    //获取用户id
                    if( !conversationId.contains(conversation_id)){
                        conversationId.add(conversation_id);
                    }
                    chatVO.setTaskId(task_id);
                    chatVO.setContent(text);
                    chatVO.setConversationId(conversation_id);
                    return chatVO;
                })
                .doFinally(signalType ->{
                    log.info("流式传输结束!");
                    if(signalType== SignalType.ON_COMPLETE||signalType==SignalType.CANCEL||signalType==SignalType.ON_ERROR){
                        if(message.getConversationId()==null) {
                            log.error("会话id为空{}",  message);
                            message.setConversationId(conversationId.get(0));
                            //数据库传入会话名称
                            ConversationNameParam conversationNameParam = new ConversationNameParam();
                            conversationNameParam.setConversationId(message.getConversationId());
                            conversationNameParam.setUser(message.getUserId());
                            //String name = difyAgentClient.makeConversationName(conversationNameParam);                            message.setConversationName(JSONObject.parseObject(name).get("name").toString());
                            //异步存储会话数据
                            RabbitMqUtil.sendMessageFanout(FANOUT_CONVERSATION, message);
                            log.error("会话名称:{}",message.getConversationName());
                        }else{
                            RabbitMqUtil.sendMessageDirect( DIRECT_CONVERSATION, message, "message");
                        }
                        message.setContent(content.toString());
                            message.setRole(Agent.AI);
                            RabbitMqUtil.sendMessageDirect(DIRECT_CONVERSATION, message, "message");
                    }
                });
    }

    /**
     * 将智能体输出的结构化数据转化为列表集合
     * @return
     */
    private List<ChatHistoryVO> getListChatHistory(String structuredData){
        JSONArray array=JSONArray.parseArray(structuredData);
        List<ChatHistoryVO> chatList=new ArrayList<>();
        for(Object arr:array){
            chatList.add(new ChatHistoryVO(Agent.USER, JSONObject.parseObject(arr.toString()).get("query").toString()));
            chatList.add(new ChatHistoryVO(Agent.AI, JSONObject.parseObject(arr.toString()).get("answer").toString()));
        }
        return chatList;
    }

    /**
     * 获取会话名称
     * @param query
     * @return
     */
    private String getConversationName(String query){
        //TODO 填写会话名称逻辑
        return null;
    }
}
